package com.hyperzsoft.predictor;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.hyperzsoft.predictor.predictor.VenueTable;
import com.hyperzsoft.predictor.team.Divisions;

public class team {
	public static final String TIMESTAMP_FORMAT = "EEE MMM d, yyyy";
	
	//division Enumeration
	public enum Divisions {ATL (0),SE (1),NE (2),NW (3),CEN (4),PAC (5);
		private Divisions(int aTable) {id = aTable;}
		
		final int value() {return id;}
		
		@Override
		public final String toString() {
			switch (id) {
				case 0: return "ATL";
				case 1: return "SE";
				case 2: return "NE";
				case 3: return "NW";
				case 4: return "CEN";
				case 5: return "PAC";
			}
			return null;
		}
		
		private final int id;
	}
	
	int position;
	String fullName;
	String acroName;
	Divisions div;
	int gamesPlayed;
	int won;
	int lost;
	int otloss;
	int points;
	int regPlusOT;
	int goalsFor;
	int goalsAga;
	String homeRec;
	String awayRec;
	String lastTen;
	String streak;
	String soRec;
	float avgGFG;
	float avgGAG;
	int goalDiff;
	float winPerc;
	int lostPoints;
	float pointPerc;
	
	Map<String, OppTeam> scheduleHome;
	Map<String, OppTeam> scheduleAway;
	
	public team() {
		scheduleHome = new HashMap<String, OppTeam>();
		scheduleAway = new HashMap<String, OppTeam>();
	}
	
	public void BuildSchedule(Element schedule, String venue) {
		OppTeam opTeam;
		Element opTeamData;
		
		for (Element gameRow : schedule.select("tr:has(td[class*=team])")) {
			opTeam = new OppTeam();
			opTeamData = (venue == VenueTable.HOME.value()) ? gameRow.select("div[class*=teamName]").first() : gameRow.select("div[class*=teamName]").last();
			opTeam.setFullName(opTeamData.text());
			opTeam.setAcroName(opTeamData.select("a").attr("rel"));
			
			if (venue == VenueTable.HOME.value()) {
				if (scheduleHome.containsKey(opTeam.getAcroName())) {
					opTeam = scheduleHome.get(opTeam.getAcroName());
				}
				opTeam.addDate(gameRow.select("div[class*=skedStartDateSite]").first().text());
				scheduleHome.put(opTeam.getAcroName(), opTeam);
			}
			if (venue == VenueTable.AWAY.value()) {
				if (scheduleAway.containsKey(opTeam.getAcroName())) {
					opTeam = scheduleAway.get(opTeam.getAcroName());
				}
				opTeam.addDate(gameRow.select("div[class*=skedStartDateSite]").first().text());
				scheduleAway.put(opTeam.getAcroName(), opTeam);
			}
		}
	}
	
	public void BuildTeamFromNode(Element teamRow) {
		Elements teamInfo;
		DecimalFormat twoDForm = new DecimalFormat("#.##");
		
		teamInfo = teamRow.select("a");
		acroName = teamInfo.first().attr("rel");
		fullName = teamInfo.get(1).text();
		
		teamInfo = teamRow.select("td").not("td[style]");
		position = Integer.parseInt(teamInfo.get(0).text());
		div = Divisions.valueOf(teamInfo.get(1).text());
		gamesPlayed = Integer.parseInt(teamInfo.get(2).text());
		won = Integer.parseInt(teamInfo.get(3).text());
		lost = Integer.parseInt(teamInfo.get(4).text());
		otloss = Integer.parseInt(teamInfo.get(5).text());
		points = Integer.parseInt(teamInfo.get(6).text());
		regPlusOT = Integer.parseInt(teamInfo.get(7).text());
		goalsFor = Integer.parseInt(teamInfo.get(8).text());
		goalsAga = Integer.parseInt(teamInfo.get(9).text());
		homeRec = teamInfo.get(11).text();
		awayRec = teamInfo.get(12).text();
		soRec = teamInfo.get(13).text();
		lastTen = teamInfo.get(14).text();
		streak = teamInfo.get(15).text();
		avgGFG = Float.valueOf(twoDForm.format((float)goalsFor / (float)gamesPlayed));
		avgGAG = Float.valueOf(twoDForm.format((float)goalsAga / (float)gamesPlayed));
		goalDiff = goalsFor - goalsAga;
		winPerc = Float.valueOf(twoDForm.format((float)won/(float)gamesPlayed));
		lostPoints = (gamesPlayed * 2) - ((won * 2) + otloss);
		pointPerc = Float.valueOf(twoDForm.format((float)(((float)won * 2) + (float)otloss) / (float)((float)gamesPlayed * 2)));
	}
}

class OppTeam {
	private String fullName;
	private String acroName;
	private ArrayList<Date> gameDates;
	Map<Long, HistoricalGame> hgGames;
	Divisions div;
	
	public OppTeam() {
		hgGames = new HashMap<Long, HistoricalGame>();
		gameDates = new ArrayList<Date>();
	}
	
	public String getFullName() {
		return fullName;
	}
	
	public void setFullName(String newValue) {
		fullName = newValue;
	}
	
	public String getAcroName() {
		return acroName;
	}
	
	public void setAcroName(String newValue) {
		acroName = newValue;
	}
	
	public Date getDate(int index) {
		return gameDates.get(index);
	}
	
	public ArrayList<Date> getDates() {
		return gameDates;
	}
	
	public void addDate(String value) {
		try {
			SimpleDateFormat format = new SimpleDateFormat(team.TIMESTAMP_FORMAT);
			gameDates.add(format.parse(value));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void BuildOpponentHistory(Element history, String teamName) {
		HistoricalGame hgGame;
		SimpleDateFormat format = new SimpleDateFormat(team.TIMESTAMP_FORMAT);
		
		try {
			for (Element gameRow : history.select("tr:has(td[class*=team])").select("tr:has(a[rel*=" + teamName + "])")) {
				hgGame = new HistoricalGame();
				//home team
				String homeTeam = gameRow.select("div[class*=teamName]").select("a").first().attr("rel").toString();
				hgGame.venue = (this.acroName == homeTeam) ? VenueTable.HOME : VenueTable.AWAY;  
				String winner = gameRow.select("td[class*=tvInfo]").select("span[class*=black]").text();
				String loser = gameRow.select("td[class*=tvInfo]").select("span:not(span[class*=black])").text(); 
				int winGoals = Integer.parseInt(winner.substring(winner.indexOf("(") + 1, winner.indexOf(")"))); 
				int losGoals = Integer.parseInt(loser.substring(loser.indexOf("(") + 1, loser.indexOf(")")));
				
				hgGame.goalsFor = (winner.contains(this.getAcroName())) ? winGoals : losGoals; 
				hgGame.goalsAga = (winner.contains(this.getAcroName())) ? losGoals : winGoals;
				
				if (loser.contains("OT") || loser.contains("S/O") && loser.contains(this.getAcroName())) {
					hgGame.result = "OTL";
				} else {
					hgGame.result = (winner.contains(this.acroName)) ? "W" : "L";
				}
				
				hgGames.put((format.parse(gameRow.select("div[class*=skedStartDateSite]").first().text())).getTime(), hgGame);
			}
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

class HistoricalGame {
	VenueTable venue;
	int goalsFor;
	int goalsAga;
	String result;
}